﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.OleDb;
using System.Text.RegularExpressions;

namespace Our.Umbraco.uDbCompare
{
    public partial class MacroInUse : System.Web.UI.UserControl
    {
        public bool UseRemoteConnectionString { get; set; }

        private static string macroTemplateTag = "umbraco:macro";
        private static string macroContentTag = "UMBRACO_MACRO";

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
                BindData();
        }

        private string connectionString
        {
            get
            {
                string connectionString = uDbCompare.CurrentConnectionString;
                if (UseRemoteConnectionString)
                    connectionString = uDbCompare.RemoteConnectionString;
                return connectionString;
            }
        }

        public void BindData()
        {
            if (uDbCompare.IsValidDbConnection(UseRemoteConnectionString))
            {
                DataTable macroTable = uDbCompare.QueryDb("select macroAlias, macroname from cmsMacro", connectionString);
                macroTable.DefaultView.Sort = "macroAlias asc";
                MacroDropDownList.DataTextField = "macroname";
                MacroDropDownList.DataValueField = "macroAlias";
                MacroDropDownList.DataSource = macroTable;
                MacroDropDownList.DataBind();

                SearchButton.Enabled = true;
            }
        }


        private DataTable FindMacro(string alias)
        {
            string macroQuery = string.Format(@"select '{0}' as MacroLocation, c.nodeId, d.text as Name, cx.xml as Data 
	                                    from cmscontentxml cx 
	                                    join cmsContent c on cx.nodeid=c.nodeid 
	                                    join cmsDocument d on c.nodeid = d.nodeid 
	                                    where d.newest = 1
	                                     and [xml] like '%{1}%'
                                    union all
                                    select '{2}' as MacroLocation, nodeId, alias as Name,design as Data
                                    from cmsTemplate where design like '%{3}%'", 
                                    LinkItem.Content, macroContentTag, LinkItem.Template, macroTemplateTag);

            DataTable dt = uDbCompare.QueryDb(macroQuery, connectionString);
            DataTable matchDt = dt.Clone();
            matchDt.Rows.Clear();
            DataRow newRow = null;

            foreach (DataRow dr in dt.Rows)
            {
                string macroLocationString = (string)dr["MacroLocation"];
                LinkItem macroLocation = (LinkItem)Enum.Parse(typeof(LinkItem), macroLocationString);
                string data = (string)dr["data"];

                switch (macroLocation)
                {
                    case LinkItem.Template:
                        // <\s*(?i)umbraco\:macro[^>]*>
                        // replace : with \: for regex
                        string regex = string.Format(@"<\s*(?i){0}[^>]*>", macroTemplateTag.Replace(":", @"\:"));

                        MatchCollection matches = Regex.Matches(data, regex);

                        foreach (Match match in matches)
                        {
                            // (?i)alias\s*=\s*["'][^"']*["']
                            string aliasRegex = string.Format(@"(?i)alias\s*=\s*[{0}']\s*{1}\s*[{0}']", "\"", alias);
                            Match aliasMatch = Regex.Match(match.Value, aliasRegex);
                            if (aliasMatch.Success)
                            {
                                if (newRow == null)
                                    newRow = matchDt.NewRow();

                                newRow["MacroLocation"] = macroLocation;
                                newRow["Name"] = dr["Name"];
                                newRow["data"] += match.Value;
                                newRow["nodeId"] = dr["nodeId"];
                            }
                        }
                        break;
                    case LinkItem.Content:
                        // <\?(?i)UMBRACO_MACRO\s*macroAlias\s*=\s*["'][^"']*["'][^>]*>
                        string umbRegex = string.Format(@"<\?(?i){1}\s*macroAlias\s*=\s*[{0}']\s*{2}\s*[{0}'][^>]*>", "\"", macroContentTag, alias);
                        Match umbMatch = Regex.Match(data, umbRegex);
                        if (umbMatch.Success)
                        {
                            if (newRow == null)
                                newRow = matchDt.NewRow();

                            newRow["MacroLocation"] = macroLocation;
                            newRow["Name"] = dr["Name"];
                            newRow["data"] += umbMatch.Value;
                            newRow["nodeId"] = dr["nodeId"];
                        }
                        break;
                }

                if (newRow != null)
                {
                    matchDt.Rows.Add(newRow);
                    newRow = null;
                }


            }

            return matchDt;
        }


        protected void SearchButton_OnClick(object sender, EventArgs e)
        {
            DataTable matchDt = FindMacro(MacroDropDownList.SelectedValue);
            MacroGridView.DataSource = matchDt;
            MacroGridView.DataBind();

            NoResultsLabel.Visible = (matchDt.Rows.Count == 0);
        }

        protected void MacroGridView_OnRowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                DataRowView drv = e.Row.DataItem as DataRowView;

                int nodeId = (int)drv["nodeId"];
                string macroLocationString = (string)drv["MacroLocation"];
                LinkItem macroLocation = (LinkItem)Enum.Parse(typeof(LinkItem), macroLocationString);

                if (macroLocation != LinkItem.Unknown)
                {
                    string url = uDbCompare.GetLinkUrl(macroLocation, nodeId, UseRemoteConnectionString);
                    uDbCompareUI.SetLinkCell(e.Row.Cells[1], nodeId.ToString(), url);
                }
            }
        }
    }
}